package dbconn

import (
	"sync"

	"iot-base/common/config"
	"iot-base/common/logger"

	"go.uber.org/zap"

	"gorm.io/driver/postgres"

	"errors"

	"gorm.io/driver/sqlite"

	"gorm.io/gorm"
	//"time"
)

//DBConnection 数据库连接
var DBConnection *gorm.DB

//DBType 数据库类型
//var DBType string

func init() {
	//gorm.DefaultTableNameHandler = func(db *gorm.DB, defaultTableName string) string {
	//	return "t_" + defaultTableName
	//}
	ConnectDB()
}

var lock sync.Mutex

//ConnectDB 连接数据库
func ConnectDB() (*gorm.DB, error) {
	if DBConnection != nil {
		return DBConnection, nil
	}
	lock.Lock()
	defer lock.Unlock()
	if DBConnection != nil {
		return DBConnection, nil
	}
	var constr string
	var err error
	if config.DBOption.Type == "postgres" {
		constr = config.DBOption.Type + "://" + config.DBOption.UserName + ":" +
			config.DBOption.Password + "@" +
			config.DBOption.DBAddr + "/" + "postgres?sslmode=disable"
		dbi, erri := gorm.Open(postgres.Open(constr), &gorm.Config{})
		if erri == nil {
			//defer dbi.Close()
			dbi.Exec("Create Database " + config.DBOption.DBName + " with owner=postgres")

		} else {
			logger.Log.Info("open database ", zap.String("dbname", config.DBOption.DBName), zap.Error(erri))
		}
		constr = config.DBOption.Type + "://" + config.DBOption.UserName + ":" +
			config.DBOption.Password + "@" +
			config.DBOption.DBAddr + "/" + config.DBOption.DBName + "?sslmode=disable"
		DBConnection, err = gorm.Open(postgres.Open(constr), &gorm.Config{})

	} else {
		constr = config.DBOption.Type + "://" + config.DBOption.DBAddr
		DBConnection, err = gorm.Open(sqlite.Open(config.DBOption.DBAddr), &gorm.Config{})
	}
	logger.Log.Info("begin connection db...", zap.String("connstr", constr))

	if err != nil {
		logger.Log.Error("db connect error", zap.Error(err))
		return nil, err
	}
	//DBType = dbType

	//db.SingularTable(true)
	//DBConnection = db
	sqlDB, _ := DBConnection.DB()
	sqlDB.SetMaxIdleConns(3)
	if config.PType == "edge" {
		sqlDB.SetMaxOpenConns(20)
	} else {
		sqlDB.SetMaxOpenConns(100)
	}

	// SetConnMaxLifetime 设置了连接可复用的最大时间。
	//sqlDB.SetConnMaxLifetime(time.Minute * time.Duration(30))
	//defer sqlDB.Close()
	return DBConnection, nil
}

func IsNotFound(err error) bool {
	return errors.Is(err, gorm.ErrRecordNotFound)
}
